package cn.kgc.gmall.utils;

import cn.kgc.gmall.common.GmallConfig;
import org.apache.commons.beanutils.BeanUtils;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * phoenix工具类
 * 连接phoenix执行sql语句封装好返回的数据
 */
public class PhoenixUtil {
    private static Connection conn;
    // 封装初始化连接对象方法
    public static void queryInit() throws Exception {
        // 1.连接phoenix  加载驱动
        Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
        // 2.获取连接对象
        conn = DriverManager.getConnection(GmallConfig.PHOENIX_SERVER);
        // 3.直接指定要查哪个数据库(schema)
        conn.setSchema(GmallConfig.HBASE_SCHEMA);
    }

    // select * from user ; user.class  传什么sql语句 指定要将数据封装到哪个类中
    // 返回值不确定 <T>List<T> : 前面的T代表泛型模板 后面的T代表列表中的泛型
    // select * from 数据库.user_info;
    public static <T>List<T> queryList(String sql,Class<T> clz){
        PreparedStatement ps = null;
        ResultSet rs = null;
        // 创建列表用来存储结果集
        List<T> list = new ArrayList<>();
        try {
            // 只考虑单例模式 如果不是单例考虑连接池 dbcp c3p0
            // mybatis orm原理对象关系映射
            if (conn == null){
                queryInit();
            }
            // 3.语句执行者
            ps = conn.prepareStatement(sql);

            // 4.执行sql语句
            rs = ps.executeQuery();
            /**
             * id   login_name  nick_name     name
             * 1	6litu9a6ah	秀秀		韦雅
             * 2	hl97ba54bup8	纨纨		上官纨
             * 3	ak1ixy1mu9y6	凡凡		成冰
             */
            // 从结果集中获取属性名
            ResultSetMetaData metaData = rs.getMetaData();
            // 5.遍历结果集
            while (rs.next()){
                // 传什么类就获取什么类的对象
                T t = clz.newInstance();
                for (int i = 1; i <= metaData.getColumnCount(); i++) {
                    // meteData中获取属性名
                    String columnName = metaData.getColumnName(i);
                    // 从结果集中获取属性值
                    Object value = rs.getObject(i);
                    // 借助工具类帮你把数据封装到对象中
                    // 假如传递进来的类下jsonObject 往里添加属性
                    // 假如传递进来的是实体类 直接为属性赋值
                    // jsonObject {clumnName:value}
                    // UserInfo userInfo.name = value
                    BeanUtils.setProperty(t,columnName,value);
                }
                list.add(t);
            }

            // 6.关流
            rs.close();
            ps.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return list;
    }

    /*public static void main(String[] args) {
        List<JSONObject> jsonObjects = queryList("select * from DIM_USER_INFO", JSONObject.class);
        for (JSONObject jsonObject : jsonObjects) {
            System.out.println(jsonObject.toJSONString());
        }
    }*/
}
